import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

public class HttpResponse {
    public HttpResponse(Socket socket) throws IOException {
        this.socket = socket;
        this.output = socket.getOutputStream();
        this.headers = new HashMap<>();
        this.statusCode = 200;
        this.statusMessage = "OK";

        // 设置默认头
        setHeader("Server", "HttpServer/1.0");
        setHeader("Date", getCurrentDate());
    }

    public void setHeader(String name, String value) {
        headers.put(name, value);
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
        this.statusMessage = getStatusMessage(statusCode);
    }

    private String getCurrentDate() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone("CST"));  // 使用中国标准时间
        return dateFormat.format(new Date());
    }

    private String getStatusMessage(int statusCode) {
        switch (statusCode) {
            case 200: return "OK";
            case 201: return "Created";
            case 400: return "Bad Request";
            case 404: return "Not Found";
            case 405: return "Method Not Allowed";
            case 500: return "Internal Server Error";
            default: return "Unknown Status";
        }
    }

    // 先设置响应头部
    private void sendHeaders() throws IOException {
        StringBuilder headerBuilder = new StringBuilder();
        headerBuilder.append("HTTP/1.0 ").append(statusCode).append(" ").append(statusMessage).append("\r\n");

        for (Map.Entry<String, String> header : headers.entrySet()) {
            headerBuilder.append(header.getKey()).append(": ").append(header.getValue()).append("\r\n");
        }
        headerBuilder.append("\r\n");

        output.write(headerBuilder.toString().getBytes(StandardCharsets.UTF_8));
    }

    // 再设置主体（发送接口）
    public void sendJson(int statusCode, JsonResponse json) throws IOException {
        setStatusCode(statusCode);
        setHeader("Content-Type", "application/json; charset=utf-8");

        String jsonString = json.toString();
        byte[] bodyBytes = jsonString.getBytes(StandardCharsets.UTF_8);
        setHeader("Content-Length", String.valueOf(bodyBytes.length));

        sendHeaders();
        output.write(bodyBytes);
        output.flush();
    }

    // 错误响应
    public void sendError(int statusCode, String message) throws IOException {
        JsonResponse errorResponse = new JsonResponse();
        errorResponse.addProperty("error", getStatusMessage(statusCode));
        errorResponse.addProperty("message", message);
        errorResponse.addProperty("statusCode", statusCode);
        errorResponse.addProperty("timestamp", System.currentTimeMillis());

        sendJson(statusCode, errorResponse);
    }

    public void close() {
        try {
            if (output != null) output.close();
            if (socket != null && !socket.isClosed()) socket.close();
        } catch (IOException e) {
            System.err.println("关闭连接出错: " + e.getMessage());
        }
    }

    // 对应连接套接字
    private final Socket socket;
    private final OutputStream output;

    // 响应格式
    private int statusCode;
    private String statusMessage;
    private final Map<String, String> headers;
}
